﻿using System;
using System.Collections.ObjectModel;
using System.Linq;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using Bymed.SpineScan.DataModel;
using Bymed.SpineScan.WPF.Model;
using Bymed.SpineScan.WPF.Shared;
using Bymed.SpineScan.Service.Shared;

namespace Bymed.SpineScan.WPF.ViewModel
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class AttendingDoctorSetupViewModel : MyViewModelBase
    {
        /// <summary>
        /// Initializes a new instance of the AttendingDoctorSetupViewModel class.
        /// </summary>
        public AttendingDoctorSetupViewModel(IDataService dataService) : base(dataService) { }

        public override void ResetProperties()
        {
            try
            {
                base.ResetProperties();

                LoadAttendingDoctorList();
            }
            catch (Exception ex)
            {
                RequestDisplayErrorMessage(ex.Message);
            }
        }

        /// <summary>
        /// The <see cref="SelectedAttendingDoctor" /> property's name.
        /// </summary>
        public const string SelectedAttendingDoctorPropertyName = "SelectedAttendingDoctor";

        private object _selectedAttendingDoctor = null;

        /// <summary>
        /// Sets and gets the SelectedAttendingDoctor property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public object SelectedAttendingDoctor
        {
            get
            {
                return _selectedAttendingDoctor;
            }

            set
            {
                if (_selectedAttendingDoctor == value)
                {
                    return;
                }

                RaisePropertyChanging(SelectedAttendingDoctorPropertyName);
                _selectedAttendingDoctor = value;
                RaisePropertyChanged(SelectedAttendingDoctorPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="AttendingDoctorList" /> property's name.
        /// </summary>
        public const string AttendingDoctorListPropertyName = "AttendingDoctorList";

        private ObservableCollection<AttendingDoctor> _attendingDoctorList = new ObservableCollection<AttendingDoctor>();

        /// <summary>
        /// Sets and gets the AttendingDoctorList property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public ObservableCollection<AttendingDoctor> AttendingDoctorList
        {
            get
            {
                return _attendingDoctorList;
            }

            set
            {
                if (_attendingDoctorList == value)
                {
                    return;
                }

                RaisePropertyChanging(AttendingDoctorListPropertyName);
                _attendingDoctorList = value;
                RaisePropertyChanged(AttendingDoctorListPropertyName);
            }
        }

        private RelayCommand<int> _moveUpCommand;

        /// <summary>
        /// Gets the MoveUpCommand.
        /// </summary>
        public RelayCommand<int> MoveUpCommand
        {
            get
            {
                return _moveUpCommand
                    ?? (_moveUpCommand = new RelayCommand<int>(
                                          p =>
                                          {
                                              SelectedAttendingDoctor = GeneralUtility.ChangeSelectedItemIndex<AttendingDoctor>(AttendingDoctorList,
                                                  p, p == 0 ? AttendingDoctorList.Count - 1 : p - 1);
                                          },
                                          p => p == -1 ? false : true));
            }
        }

        private RelayCommand<int> _moveDownCommand;

        /// <summary>
        /// Gets the MoveDownCommand.
        /// </summary>
        public RelayCommand<int> MoveDownCommand
        {
            get
            {
                return _moveDownCommand
                    ?? (_moveDownCommand = new RelayCommand<int>(
                                          p =>
                                          {
                                              SelectedAttendingDoctor = GeneralUtility.ChangeSelectedItemIndex<AttendingDoctor>(AttendingDoctorList,
                                                  p, p == AttendingDoctorList.Count - 1 ? 0 : p + 1);
                                          },
                                          p => p == -1 ? false : true));
            }
        }

        private RelayCommand _saveCommand;

        /// <summary>
        /// Gets the SaveCommand.
        /// </summary>
        public RelayCommand SaveCommand
        {
            get
            {
                return _saveCommand
                    ?? (_saveCommand = new RelayCommand(
                                          () =>
                                          {
                                              try
                                              {
                                                  ServiceFactory.CreateAttendingDoctorService().Synchronize(AttendingDoctorList);

                                                  // Send ReturnHomeMessage to PageBase.
                                                  Messenger.Default.Send<int>(0, MainViewModel.ReturnHomeMessageToken);
                                              }
                                              catch (Exception ex)
                                              {
                                                  RequestDisplayErrorMessage(ex.Message);
                                              }
                                          }));
            }
        }

        /// <summary>
        /// Load the data from data source for initializing DiagnosticMessageReferenceList. 
        /// </summary>
        private void LoadAttendingDoctorList()
        {
            var attendingDoctorList = ServiceFactory.CreateAttendingDoctorService().GetAll().OrderBy(d => d.OrderIndex);
            AttendingDoctorList = new ObservableCollection<AttendingDoctor>(attendingDoctorList);
        }
    }
}